#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<stdbool.h>
#include<stdlib.h>


typedef int STDataType;
typedef struct Stack
{
	STDataType* array;
	int size;
	int capacity;
}Stack;
void StackInit(Stack* ps);
void StackPush(Stack* ps, STDataType data);
void StackPop(Stack* ps);
STDataType StackTop(Stack* ps);
int StackSize(Stack* ps);
int StackEmpty(Stack* ps);
void StackDestroy(Stack* ps);

void CheckCapacity(Stack* ps)
{
	if (ps->size == ps->capacity)
	{
		ps->capacity *= 2;
		ps->array = (STDataType*)realloc(ps->array, ps->capacity * sizeof(STDataType));
	}
}

void StackInit(Stack* ps)
{
	ps->array = (STDataType*)calloc(4, sizeof(STDataType));
	ps->capacity = 4;
	ps->size = 0;
}

void StackPush(Stack* ps, STDataType x)
{
	CheckCapacity(ps);

	ps->array[ps->size] = x;
	ps->size++;
}

void StackPop(Stack* ps)
{
	if (ps->size == 0)
	{
		return;
	}
	ps->size--;
}

STDataType StackTop(Stack* ps)
{
	if (ps->size == 0)
	{
		return (STDataType)0;
	}
	return ps->array[ps->size - 1];
}

int StackEmpty(Stack* ps)
{
	return ps->size == 0;
}

int StackSize(Stack* ps)
{
	return ps->size;
}

void StackDestory(Stack* ps)
{
	if (ps->array)
	{
		free(ps->array);
		ps->array = NULL;
		ps->size = 0;
		ps->capacity = 0;
	}
}



typedef struct {
	Stack pushst;
	Stack popst;
} MyQueue;


MyQueue* myQueueCreate() {
	MyQueue* obj = (MyQueue*)malloc(sizeof(MyQueue));

	StackInit(&obj->pushst);
	StackInit(&obj->popst);
	return obj;
}

void myQueuePush(MyQueue* obj, int x) {
	StackPush(&obj->pushst, x);
}

int myQueuePop(MyQueue* obj) {
	if (StackEmpty(&obj->popst))
	{
		while (!StackEmpty(&obj->pushst))
		{
			StackPush(&obj->popst, StackTop(&obj->pushst));
			StackPop(&obj->pushst);
		}
	}

	int top = StackTop(&obj->popst);
	StackPop(&obj->popst);
	return top;
}

int myQueuePeek(MyQueue* obj) {
	if (StackEmpty(&obj->popst))
	{
		while (!StackEmpty(&obj->pushst))
		{
			StackPush(&obj->popst, StackTop(&obj->pushst));
			StackPop(&obj->pushst);
		}
	}
	return StackTop(&obj->popst);
}

bool myQueueEmpty(MyQueue* obj) {
	return StackEmpty(&obj->popst) && StackEmpty(&obj->pushst);
}

void myQueueFree(MyQueue* obj) {
	StackDestroy(&obj->popst);
	StackDestroy(&obj->pushst);

	free(obj);

}
int main()
{
	MyQueue* obj = myQueueCreate();
	myQueuePush(obj, 1);
	myQueuePush(obj, 2);
	int ret = myQueuePeek(obj);

	return 0;
}


//typedef struct {
//    int* a;
//    int front;
//    int back;
//    int k;
//} MyCircularQueue;
//
//bool myCircularQueueIsEmpty(MyCircularQueue* obj) {
//    return obj->front == obj->back;
//}
//
//bool myCircularQueueIsFull(MyCircularQueue* obj) {
//    return (obj->back + 1) % (obj->k + 1) == obj->front;
//}
//MyCircularQueue* myCircularQueueCreate(int k) {
//    MyCircularQueue* obj = (MyCircularQueue*)malloc(sizeof(MyCircularQueue));
//    obj->a = (int*)malloc(sizeof(int) * (k + 1));
//    if (obj->a == NULL)
//    {
//        return NULL;
//    }
//    obj->front = 0;
//    obj->back = 0;
//    obj->k = k;
//
//    return obj;
//}
//
//bool myCircularQueueEnQueue(MyCircularQueue* obj, int value) {
//    if (myCircularQueueIsFull(obj))
//    {
//        return false;
//    }
//    else
//    {
//        obj->a[obj->back] = value;
//        obj->back++;
//        obj->back %= obj->k + 1;
//        return true;
//    }
//}
//
//bool myCircularQueueDeQueue(MyCircularQueue* obj) {
//    if (myCircularQueueIsEmpty(obj))
//    {
//        return false;
//    }
//    else
//    {
//        obj->front++;
//        obj->front %= obj->k + 1;
//        return true;
//    }
//}
//
//int myCircularQueueFront(MyCircularQueue* obj) {
//    if (myCircularQueueIsEmpty(obj))
//        return -1;
//
//    return obj->a[obj->front];
//}
//
//int myCircularQueueRear(MyCircularQueue* obj) {
//    if (myCircularQueueIsEmpty(obj))
//        return -1;
//    //if (myCircularQueueIsFull(obj))
//    //    return obj->a[obj->k - 1];
//
//    //return obj->a[obj->back - 1];
//    return obj->a[(obj->back-1+obj->k+1)%(obj->k+1)];
//}
//void myCircularQueueFree(MyCircularQueue* obj) {
//    free(obj->a);
//    obj->a = NULL;
//    free(obj);
//}
//int main()
//{
//    MyCircularQueue* obj = myCircularQueueCreate(3);
//    myCircularQueueEnQueue(obj, 1);
//    myCircularQueueEnQueue(obj, 2);
//    myCircularQueueEnQueue(obj, 3);
//    myCircularQueueEnQueue(obj, 4);
//
//    int ret1 = myCircularQueueRear(obj);
//    int ret2 = myCircularQueueIsFull(obj);
//    myCircularQueueDeQueue(obj);
//    myCircularQueueEnQueue(obj, 4);
//    int ret3 = myCircularQueueRear(obj);
//
//
//    return 0;
//}